import os
from tkinter import messagebox
from app.audio_processor import AudioProcessor
from app.utils import format_duration, play_audio_file, search_song_in_list


class PlaylistManager:
    """歌单管理器，负责歌单的加载、保存、编辑等核心功能"""
    
    def __init__(self):
        """初始化歌单管理器"""
        self.current_playlist_path = None  # 当前歌单文件路径
        self.songs = []  # 当前歌单中的歌曲列表
        self.song_tree = None  # 歌曲列表视图控件
        
    def set_song_tree(self, song_tree):
        """设置歌曲列表视图控件"""
        self.song_tree = song_tree
    
    def new_playlist(self, root):
        """创建新的歌单"""
        # 检查是否需要保存当前歌单
        if self.songs and messagebox.askyesno("保存", "是否保存当前歌单？"):
            if not self.save_playlist():
                return
        
        # 清空当前歌单
        self.clear_playlist()
        self.current_playlist_path = None
        root.title("歌单管理器 - 未命名")
    
    def load_playlist(self, file_path, root):
        """加载歌单文件"""
        try:
            self.clear_playlist()
            self.current_playlist_path = file_path
            root.title(f"歌单管理器 - {os.path.basename(file_path)}")
            
            with open(file_path, 'r', encoding='utf-8') as f:
                lines = f.readlines()
            
            # 解析M3U文件
            for line in lines:
                line = line.strip()
                if line and not line.startswith('#'):
                    # 检查文件是否存在
                    if os.path.exists(line):
                        self.add_song(line)
                    elif os.path.exists(os.path.join(os.path.dirname(file_path), line)):
                        # 尝试相对路径
                        self.add_song(os.path.join(os.path.dirname(file_path), line))
            
            messagebox.showinfo("成功", f"歌单已加载，共 {len(self.songs)} 首歌曲")
        except Exception as e:
            messagebox.showerror("错误", f"加载歌单失败: {str(e)}")
    
    def save_playlist(self):
        """保存当前歌单"""
        if not self.current_playlist_path:
            return False
        
        try:
            with open(self.current_playlist_path, 'w', encoding='utf-8') as f:
                f.write("#EXTM3U\n")
                for song in self.songs:
                    # 写入扩展信息
                    duration = int(song['duration'] * 1000)  # 转换为毫秒
                    title = song['title'] or os.path.basename(song['path'])
                    artist = song['artist'] or "Unknown"
                    f.write(f"#EXTINF:{duration},{artist} - {title}\n")
                    # 写入文件路径（相对路径）
                    rel_path = os.path.relpath(song['path'], os.path.dirname(self.current_playlist_path))
                    f.write(f"{rel_path}\n")
            
            messagebox.showinfo("成功", "歌单已保存")
            return True
        except Exception as e:
            messagebox.showerror("错误", f"保存歌单失败: {str(e)}")
            return False
    
    def add_song(self, file_path):
        """添加歌曲到歌单"""
        try:
            # 获取音频文件信息
            audio_info = AudioProcessor.get_audio_info(file_path)
            
            # 检查是否已存在
            for song in self.songs:
                if song['path'] == file_path:
                    return
            
            # 添加到歌曲列表
            self.songs.append({
                'path': file_path,
                'filename': os.path.basename(file_path),
                'artist': audio_info.get('artist', ''),
                'title': audio_info.get('title', ''),
                'duration': audio_info.get('duration', 0)
            })
            
            # 更新列表视图
            if self.song_tree:
                duration_str = format_duration(audio_info.get('duration', 0))
                self.song_tree.insert("", "end", values=(
                    os.path.basename(file_path),
                    audio_info.get('artist', ''),
                    audio_info.get('title', ''),
                    duration_str
                ))
        except Exception as e:
            print(f"添加歌曲失败: {file_path}, 错误: {str(e)}")
    
    def remove_selected(self):
        """删除选中的歌曲"""
        if not self.song_tree:
            return
        
        selected_items = self.song_tree.selection()
        if not selected_items:
            messagebox.showinfo("提示", "请先选择要删除的歌曲")
            return
        
        # 确认删除
        if messagebox.askyesno("确认", f"确定要删除选中的 {len(selected_items)} 首歌曲吗？"):
            # 从后往前删除，避免索引问题
            for item in reversed(selected_items):
                index = self.song_tree.index(item)
                self.songs.pop(index)
                self.song_tree.delete(item)
    
    def clear_playlist(self):
        """清空当前歌单"""
        if self.songs and messagebox.askyesno("确认", "确定要清空当前歌单吗？"):
            self.songs.clear()
            if self.song_tree:
                for item in self.song_tree.get_children():
                    self.song_tree.delete(item)
    
    def sort_playlist(self, key, order):
        """排序歌单中的歌曲"""
        if not self.songs:
            return
        
        # 根据不同的键进行排序
        if key == "filename":
            self.songs.sort(key=lambda x: x['filename'].lower(), reverse=(order == "desc"))
        elif key == "artist":
            self.songs.sort(key=lambda x: x['artist'].lower(), reverse=(order == "desc"))
        elif key == "title":
            self.songs.sort(key=lambda x: x['title'].lower(), reverse=(order == "desc"))
        elif key == "duration":
            self.songs.sort(key=lambda x: x['duration'], reverse=(order == "desc"))
        
        # 更新列表视图
        self.refresh_song_list()
    
    def refresh_song_list(self):
        """刷新歌曲列表视图"""
        if not self.song_tree:
            return
        
        # 清空当前列表
        for item in self.song_tree.get_children():
            self.song_tree.delete(item)
        
        # 重新添加所有歌曲
        for song in self.songs:
            duration_str = format_duration(song['duration'])
            self.song_tree.insert("", "end", values=(
                song['filename'],
                song['artist'],
                song['title'],
                duration_str
            ))
    
    def move_song(self, direction):
        """移动选中的歌曲位置"""
        if not self.song_tree:
            return
        
        selected_items = self.song_tree.selection()
        if not selected_items or len(selected_items) > 1:
            messagebox.showinfo("提示", "请选择一首歌曲进行移动")
            return
        
        item = selected_items[0]
        index = self.song_tree.index(item)
        
        if direction == "up" and index > 0:
            # 上移
            self.songs[index], self.songs[index-1] = self.songs[index-1], self.songs[index]
            self.refresh_song_list()
            # 重新选中移动后的歌曲
            new_index = index - 1
        elif direction == "down" and index < len(self.songs) - 1:
            # 下移
            self.songs[index], self.songs[index+1] = self.songs[index+1], self.songs[index]
            self.refresh_song_list()
            # 重新选中移动后的歌曲
            new_index = index + 1
        else:
            return
        
        new_item = self.song_tree.get_children()[new_index]
        self.song_tree.selection_set(new_item)
        self.song_tree.focus(new_item)
    
    def search_song(self, search_text):
        """搜索歌曲"""
        if not search_text or not self.song_tree:
            return
        
        # 搜索匹配的歌曲
        index = search_song_in_list(self.songs, search_text)
        if index != -1:
            # 选中并滚动到找到的歌曲
            item = self.song_tree.get_children()[index]
            self.song_tree.selection_set(item)
            self.song_tree.focus(item)
            self.song_tree.see(item)
        else:
            messagebox.showinfo("提示", f"未找到包含 '{search_text}' 的歌曲")
    
    def play_song(self):
        """播放选中的歌曲"""
        if not self.song_tree:
            return
        
        selected_items = self.song_tree.selection()
        if not selected_items:
            return
        
        item = selected_items[0]
        index = self.song_tree.index(item)
        
        play_audio_file(self.songs[index]['path'])
    
    def reorder_songs(self, dragged_index, target_index):
        """重新排序歌曲（用于拖放功能）"""
        if dragged_index != target_index:
            # 移动歌曲
            song = self.songs.pop(dragged_index)
            self.songs.insert(target_index, song)
            
            # 更新列表
            self.refresh_song_list()
            
            return target_index
        
        return dragged_index